#include <cstdio>
#include <stack>
#include <vector>

const int N = 100005;
int n, m, k, fa[N << 1], u[N << 1], v[N << 1], dep[N << 1];
std::stack<std::pair<int, int> > stk;

struct Node {
  std::vector<int> e;
} tr[N << 2];

int find(int x) { return fa[x] == x ? x : find(fa[x]); }

inline void merge(int x, int y) {
  if (x == y) return;
  if (dep[x] > dep[y]) std::swap(x, y);
  stk.push(std::make_pair(x, dep[x] == dep[y])), fa[x] = y, dep[y] += dep[x] == dep[y];
}

void insert(int x, int l, int r, int L, int R, int id) {
  if (L <= l && r <= R) {
    tr[x].e.push_back(id);
    return;
  }
  int mid = (l + r) >> 1;
  if (L <= mid) insert(x << 1, l, mid, L, R, id);
  if (mid < R) insert(x << 1 | 1, mid + 1, r, L, R, id);
}

void dfs(int x, int l, int r) {
  bool flag = true;
  size_t siz = stk.size();
  for (std::vector<int>::iterator iter = tr[x].e.begin(); iter != tr[x].e.end(); ++iter) {
    int from = find(u[*iter]), to = find(v[*iter]);
    if (from == to) {
      for (int j = l; j <= r; ++j) puts("No");
      flag = false;
      break;
    }
    merge(find(u[*iter] + N), to), merge(find(v[*iter] + N), from);
  }
  int mid = (l + r) >> 1;
  if (flag) {
    if (l == r)
      puts("Yes");
    else
      dfs(x << 1, l, mid), dfs(x << 1 | 1, mid + 1, r);
  }
  while (stk.size() > siz)
    dep[fa[stk.top().first]] -= stk.top().second, fa[stk.top().first] = stk.top().first,
                                                  stk.pop();
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#endif
#ifndef LOCAL
  freopen("SegTreeDiv.in", "r", stdin);
  freopen("SegTreeDiv.out", "w", stdout);
#endif
#endif

  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1, l, r; i <= m; ++i) {
    scanf("%d%d%d%d", &u[i], &v[i], &l, &r);
    if (l != r) insert(1, 1, k, l + 1, r, i);
  }
  for (int i = 1; i <= n; ++i) fa[i] = i, fa[i + N] = i + N;
  dfs(1, 1, k);
  return 0;
}